package com.zhitan.ems.app.sse;

import java.nio.charset.StandardCharsets;
import java.util.concurrent.CompletableFuture;

import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import com.zhitan.ems.common.utils.uuid.IdUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * UTF-8编码的SSE发射器
 * 解决SSE中文乱码问题
 * 
 * @author zhitan
 */
@Slf4j
public class SseEmitterUTF8 extends SseEmitter {
    
    /**
     * 连接唯一标识
     */
    private String uuid;
    
    /**
     * 连接创建时间
     */
    private final long createTime;
    
    /**
     * 构造函数
     * 
     * @param timeout 超时时间(毫秒)
     */
    public SseEmitterUTF8(Long timeout) {
        super(timeout);
        this.uuid = IdUtils.fastUUID();
        this.createTime = System.currentTimeMillis();
    }

    /**
     * 扩展响应头，设置UTF-8编码
     * 
     * @param outputMessage 服务器HTTP响应
     */
    @Override
    protected void extendResponse(ServerHttpResponse outputMessage) {
        super.extendResponse(outputMessage);
        HttpHeaders headers = outputMessage.getHeaders();
        headers.setContentType(new MediaType(MediaType.TEXT_EVENT_STREAM, StandardCharsets.UTF_8));
    }

    /**
     * 获取连接唯一标识
     * 
     * @return UUID
     */
    public String getUuid() {
        return uuid;
    }

    /**
     * 设置连接唯一标识
     * 
     * @param uuid UUID
     */
    public void setUuid(String uuid) {
        this.uuid = uuid;
    }
    
    /**
     * 获取连接创建时间
     * 
     * @return 创建时间戳
     */
    public long getCreateTime() {
        return createTime;
    }
    
    /**
     * 异步发送消息
     * 
     * @param object 消息对象
     * @return CompletableFuture
     */
    public CompletableFuture<Void> sendAsync(Object object) {
        return CompletableFuture.runAsync(() -> {
            try {
                this.send(object);
            } catch (Exception e) {
                log.error("异步发送SSE消息失败，连接UUID：{}", this.uuid, e);
                throw new RuntimeException(e);
            }
        });
    }
    
    /**
     * 异步发送事件消息
     * 
     * @param event 事件构建器
     * @return CompletableFuture
     */
    public CompletableFuture<Void> sendAsync(SseEventBuilder event) {
        return CompletableFuture.runAsync(() -> {
            try {
                this.send(event);
            } catch (Exception e) {
                log.error("异步发送SSE事件消息失败，连接UUID：{}", this.uuid, e);
                throw new RuntimeException(e);
            }
        });
    }
}